<?php
	class cThread
	{
		private $m_obj_Pref; // process reference
		private $m_arr_Pipes; // stdio
		private $m_str_Buffer; // output buffer
		/* private */
		function __construct()
		{
			$this->m_obj_Pref = 0;
			$this->m_str_Buffer = "";
			$this->m_arr_Pipes = array();
		}

		public static function Create($str_File, $str_PHPCommand = "php")
		{
			$obj_Thread = new cThread();
			$arr_Descriptor = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
			$obj_Thread->m_obj_Pref = proc_open($str_PHPCommand . " -q $str_File ", $arr_Descriptor, $obj_Thread->m_arr_Pipes);
			stream_set_blocking($obj_Thread->m_arr_Pipes[1], 0);
			return $obj_Thread;
		}

		public function isActive()
		{
			$this->m_str_Buffer .= $this->listen();
			$f = stream_get_meta_data($this->m_arr_Pipes[1]);
			return !$f["eof"];
		}

		public function close()
		{
			foreach($this->m_arr_Pipes as $obj_Pipe)
			{
				fclose($obj_Pipe);
			}
			$r = proc_close($this->m_obj_Pref);
			$this->m_obj_Pref = NULL;
			return $r;
		}

		public function tell($str_Thought)
		{
			fwrite($this->m_arr_Pipes[0], $str_Thought);
		}

		public function listen($bool_All = true)
		{
			$m_str_Buffer = $this->m_str_Buffer;
			$this->m_str_Buffer = "";
			while ($r = fgets($this->m_arr_Pipes[1]))
			{
				$m_str_Buffer .= $r;
				if(!$bool_All)
				{
					break;
				}
			}
			return $m_str_Buffer;
		}

		public function getError()
		{
			$m_str_Buffer = "";
			while ($r = fgets($this->m_arr_Pipes[2], 1024))
			{
				$m_str_Buffer .= $r;
			}
			return $m_str_Buffer;
		}
	}
?>